package com.tangcco.lockwell.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import com.google.common.collect.Lists;
import com.tangcco.lockwell.context.WebContext;
import com.tangcco.lockwell.domain.*;
import com.tangcco.lockwell.domain.dto.StatisticalStudyReportDto;
import com.tangcco.lockwell.domain.dto.StatisticalStudyReportParentDto;
import com.tangcco.lockwell.domain.dto.english.AnswerEnglishKeyValueDto;
import com.tangcco.lockwell.domain.dto.politics.AnswerPoliticsChildDto;
import com.tangcco.lockwell.domain.enums.ExamPaperTypeEnum;
import com.tangcco.lockwell.repository.*;
import com.tangcco.lockwell.service.AnswerContentRecordService;
import com.tangcco.lockwell.service.QuestionService;
import com.tangcco.lockwell.viewmodel.admin.question.QuestionVm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 输入型题目答题记录
 * @author yanxinping
 * @version 1.0
 * @description: TODO
 * @date 2024/12/23 9:50
 */
@Slf4j
@Service
public class AnswerContentRecordServiceImpl implements AnswerContentRecordService {
    @Autowired
    private AnswerContentRecordMapper answerContentRecordMapper;
    @Autowired
    private QuestionService questionService;
    @Autowired
    private AnswerContentHistoryMapper answerContentHistoryMapper;
    @Autowired
    private AnswerContentHistoryChildMapper answerContentHistoryChildMapper;
    @Autowired
    private WebContext webContext;
    @Autowired
    private DataDictionaryServiceImpl dictionaryService;
    @Autowired
    private UserAnswerRecordMapper userAnswerRecordMapper;
    @Autowired
    private UserAnswerRecordChildMapper userAnswerRecordChildMapper;
    @Autowired
    private ExamPaperMapper examPaperMapper;
    @Override
    public int insert(AnswerContentRecord record) {
        return answerContentRecordMapper.insertSelective(record);
    }

    @Override
    public int update(AnswerContentRecord record) {
        return answerContentRecordMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    @Async("asyncServiceExecutor")
    public void insertOrUpdateForPolitics(Boolean isTest,BigDecimal score,List<AnswerPoliticsChildDto> list, ExamPaper examPaper, Integer userId,Long totalTimeSpent,
                                          List<AnswerPoliticsChildDto> thisTimeData) {
        if(CollectionUtil.isNotEmpty(list)){
            //轴测历史
            List<AnswerContentHistoryChild> childList = Lists.newArrayList();
            //刷题历史
            List<UserAnswerRecordChild> userChildList = Lists.newArrayList();
            Integer type = isTest ? ExamPaperTypeEnum.WEEKTEST.getCode() : ExamPaperTypeEnum.EXERCISE.getCode();
            for(AnswerPoliticsChildDto answer:list){
                List<AnswerContentRecord> records = answerContentRecordMapper.selectByUser(examPaper.getPaperId(),answer.getQuestionId(),userId,type);
                if(CollectionUtil.isNotEmpty(records)){
                    answerContentRecordMapper.deleteByUser(examPaper.getPaperId(),answer.getQuestionId(),userId,type);
                }
                List<String> arrayList;
                if(answer.getUserAnswer() instanceof List){
                    arrayList = (List<String>)answer.getUserAnswer();
                }else{
                    arrayList = Arrays.asList(answer.getUserAnswer().toString());
                }
                Question question = questionService.selectBaseInfoById(answer.getQuestionId());
                AnswerContentRecord acr = new AnswerContentRecord();
                acr.setAnswerUserId(userId);
                acr.setQuestionId(question.getId());
                acr.setExamPaperId(examPaper.getPaperId());
                acr.setSubjectId(question.getSubjectId());
                acr.setSubjectParentId(question.getSubjectParentId());
                //因为政治是多选题，不存在像英语阅读理解和完形填空一样的一个question多个qtitle的情况，所以这里直接将答案排序后存入content字段
                arrayList.sort(String::compareTo);
                acr.setContent(arrayList);
                acr.setType(type);
                answerContentRecordMapper.insertSelective(acr);
                if(isTest){
                    //如果是周测，则记录历史
                    AnswerContentHistoryChild child = new AnswerContentHistoryChild();
                    BeanUtil.copyProperties(acr,child,CopyOptions.create().setIgnoreProperties("id"));
                    //child.setContent(acr.getContent());
                    childList.add(child);
                }else{
                    //记录本次答题操作的数据
                    if(CollectionUtil.isNotEmpty(thisTimeData)){
                        List<Integer> thisQuestionIds = thisTimeData.stream().map(AnswerPoliticsChildDto::getQuestionId).collect(Collectors.toList());
                        if(thisQuestionIds.contains(question.getId())){
                            UserAnswerRecordChild userChild = new UserAnswerRecordChild();
                            BeanUtil.copyProperties(acr,userChild,CopyOptions.create().setIgnoreProperties("id"));
                            //child.setContent(acr.getContent());
                            userChildList.add(userChild);
                        }
                    }
                }
            }
            if(isTest){
                //记录周测历史
                AnswerContentHistory history = new AnswerContentHistory();
                history.setExamPaperId(examPaper.getPaperId());
                history.setUserId(userId);
                history.setSubjectId(examPaper.getSubjectId());
                history.setSubjectParentId(examPaper.getSubjectParentId());
                history.setCreateTime(new Date());
                history.setTotalTimeSpent(totalTimeSpent);
                history.setScore(score);
                answerContentHistoryMapper.insertSelective(history);
                //记录子信息
                childList.forEach(child -> {
                    child.setParentId(history.getId());
                    answerContentHistoryChildMapper.insertSelective(child);
                });
            }else{
                //记录每次修改的题目，不需要计算成绩，但需要记录每次修改的题目，而不是记录所有题目，这张表用于统计用户学习进度、学习报告
                //因为上面是记录周测的，周测是所有题目都做的，这里是记录刷题的，刷题可能只做了一部分题目，所以这里记录每次修改的题目
                //这里的记录是为了统计用户学习进度、学习报告，所以不需要计算成绩，只记录题目id和题目内容即可
                if( CollectionUtil.isNotEmpty(thisTimeData)){
                    //记录历史
                    UserAnswerRecord userAnswerRecord= new UserAnswerRecord();
                    userAnswerRecord.setExamPaperId(examPaper.getPaperId());
                    userAnswerRecord.setUserId(userId);
                    userAnswerRecord.setSubjectId(examPaper.getSubjectId());
                    userAnswerRecord.setSubjectParentId(examPaper.getSubjectParentId());
                    userAnswerRecord.setCreateTime(new Date());
                    userAnswerRecord.setTotalTimeSpent(totalTimeSpent);
                    userAnswerRecordMapper.insertSelective(userAnswerRecord);
                    //记录子信息
                    userChildList.forEach(child -> {
                        child.setParentId(userAnswerRecord.getId());
                        userAnswerRecordChildMapper.insertSelective(child);
                    });
                }
            }
        }
    }

    @Override
    @Async("asyncServiceExecutor")
    public void insertOrUpdateForEnglish(Boolean isTest,List<AnswerEnglishKeyValueDto> list, ExamPaper examPaper, Integer userId,Integer questionId,Long totalTimeSpent) {
        if(CollectionUtil.isNotEmpty(list)){
            List<UserAnswerRecordChild> userChildList = Lists.newArrayList();
            Integer type = isTest ? ExamPaperTypeEnum.WEEKTEST.getCode() : ExamPaperTypeEnum.EXERCISE.getCode();
            AnswerEnglishKeyValueDto existInfo = list.get(0);
            List<AnswerContentRecord> records = answerContentRecordMapper.selectByUserAndIndex(examPaper.getPaperId(),questionId,userId,existInfo.getIndex(),type);
            if(CollectionUtil.isNotEmpty(records)){
//                answerContentRecordMapper.deleteByUserAndIndex(examPaper.getPaperId(),questionId,userId,type);
                records.forEach(record -> {
                    answerContentRecordMapper.deleteByPrimaryKey(record.getId());
                });
            }
            list.forEach(record -> {
                Question question = questionService.selectBaseInfoById(questionId);
                AnswerContentRecord acr = new AnswerContentRecord();
                acr.setAnswerUserId(userId);
                acr.setQuestionId(question.getId());
                acr.setExamPaperId(examPaper.getPaperId());
                acr.setSubjectId(question.getSubjectId());
                acr.setSubjectParentId(question.getSubjectParentId());
                acr.setAnswerOptionsIndex(record.getIndex());
                acr.setContent(Arrays.asList(record.getValue()));
                acr.setType(type);
                answerContentRecordMapper.insertSelective(acr);
                AnswerContentHistoryChild child = new AnswerContentHistoryChild();
                UserAnswerRecordChild userChild = new UserAnswerRecordChild();
                // 设置拷贝选项，忽略 id 字段
                BeanUtil.copyProperties(acr,child,CopyOptions.create().setIgnoreProperties("id"));
                BeanUtil.copyProperties(acr,userChild,CopyOptions.create().setIgnoreProperties("id"));
//                child.setContent(acr.getContent());
                if(!isTest){
                    userChildList.add(userChild);
                }

            });
            if(!isTest){
                //记录刷题
                UserAnswerRecord userRecord = new UserAnswerRecord();
                userRecord.setExamPaperId(examPaper.getPaperId());
                userRecord.setSubjectId(examPaper.getSubjectId());
                userRecord.setSubjectParentId(examPaper.getSubjectParentId());
                userRecord.setCreateTime(new Date());
                userRecord.setTotalTimeSpent(totalTimeSpent);
                userRecord.setUserId(userId);
                userAnswerRecordMapper.insertSelective(userRecord);
                //记录子信息
                userChildList.forEach(child -> {
                    child.setParentId(userRecord.getId());
                    userAnswerRecordChildMapper.insertSelective(child);
                });
            }
        }
    }
    @Override
    public void calcutateEnglishScore(Integer examPaperId,Long totalTimeSpent) {
        List<AnswerContentHistoryChild> childList = Lists.newArrayList();
        ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(examPaperId);
            //计算分数
        BigDecimal score = BigDecimal.ZERO;
        List<AnswerContentRecord> records = answerContentRecordMapper.selectByExamPaperIdAndUserId(examPaper.getPaperId(),webContext.getCurrentUser().getUserId(),ExamPaperTypeEnum.WEEKTEST.getCode());
        if(CollectionUtil.isNotEmpty(records)){
            for(AnswerContentRecord record:records){
                if(record.getQuestionId()!=null) {
                    AnswerContentHistoryChild child = new AnswerContentHistoryChild();
                    QuestionVm questionVm = questionService.selectById(record.getQuestionId());
                    if (questionVm != null && StringUtils.isNotBlank(questionVm.getCorrect())) {
                        if(CollectionUtil.isEmpty(record.getContent())){
                            continue;
                        }
                        String userAnswer = record.getContent().get(0);
                        //计算每道题的分数
                        List<String> correctAnswer = Arrays.asList(questionVm.getCorrect().split(","));
                        //这道题的总分
                        BigDecimal correctSumScore = questionVm.getScore() == null ? BigDecimal.ZERO : BigDecimal.valueOf(questionVm.getScore());
                        //拆分出子题目的分数 = 总分/子题目数量
                        BigDecimal correctScore =  correctSumScore.divide(BigDecimal.valueOf(correctAnswer.size()), 2, BigDecimal.ROUND_HALF_UP);
                        //判断答案是否正确
                        if(correctAnswer.contains(userAnswer)){
                            score = score.add(correctScore);
                        }
                    }else{
                        BigDecimal divNum = NumberUtil.mul(BigDecimal.valueOf(questionVm.getScore() == null ? 0 : questionVm.getScore()), BigDecimal.valueOf(0.8));
                        score = score.add(divNum);
                    }
                    // 设置拷贝选项，忽略 id 字段
                    BeanUtil.copyProperties(record, child,CopyOptions.create().setIgnoreProperties("id"));
                    childList.add(child);
                }
            }
            //记录周测历史
            AnswerContentHistory history = new AnswerContentHistory();
            history.setExamPaperId(examPaper.getPaperId());
            history.setSubjectId(examPaper.getSubjectId());
            history.setSubjectParentId(examPaper.getSubjectParentId());
            history.setCreateTime(new Date());
            history.setTotalTimeSpent(totalTimeSpent);
            history.setUserId(webContext.getCurrentUser().getUserId());
            history.setScore(score);
            answerContentHistoryMapper.insertSelective(history);
            //记录子信息
            childList.forEach(child -> {
                child.setParentId(history.getId());
                answerContentHistoryChildMapper.insertSelective(child);
            });
        }
    }

    @Override
    public List<AnswerContentRecord> selectByExamPaperIdAndUserId(Integer type,Integer examPaperId, Integer userId) {
        List<AnswerContentRecord> records =  answerContentRecordMapper.selectByExamPaperIdAndUserId(examPaperId,userId,type);
        return records.stream().filter(record -> record.getQuestionId()!= null).collect(Collectors.toList());
    }
    @Override
    public List<AnswerContentRecord> selectByExamPaperIdAndUserIdAndQuestionId(Integer type,Integer examPaperId, Integer userId,Integer questionId) {
        List<AnswerContentRecord> records =  answerContentRecordMapper.selectByExamPaperIdAndUserIdAndQuestionId(examPaperId,userId,type,questionId);
        return records.stream().filter(record -> record.getQuestionId()!= null).collect(Collectors.toList());
    }
    @Override
    public StatisticalStudyReportParentDto statisticalStudyReport(Integer week, Integer userId) {
        StatisticalStudyReportParentDto result = new StatisticalStudyReportParentDto();
        result.setCurrentWeek(week);
        List<StatisticalStudyReportDto> childList =  userAnswerRecordMapper.statisticalByUserId(userId==null?webContext.getCurrentUser().getUserId():userId);
        List<StatisticalStudyReportDto> resultChildList = Lists.newArrayList();
        childList = childList.stream().filter(dto -> Objects.equals(dto.getWeekInfo(), week)).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(childList)){
            //计算总时长，四舍五入到小时
            BigDecimal hoursSpent = childList.stream().map(StatisticalStudyReportDto::getHoursSpent).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
            result.setTotalHours(hoursSpent);
            Integer totalQuestions = childList.stream().map(StatisticalStudyReportDto::getQuestionsCompleted).reduce(0, Integer::sum);
            result.setTotalCompletedQuestions(totalQuestions);
            Map<String,List<StatisticalStudyReportDto>> mapList = childList.stream().collect(Collectors.groupingBy(StatisticalStudyReportDto::getWeekday));
            if(CollectionUtil.isNotEmpty(mapList)){
                for(Map.Entry<String,List<StatisticalStudyReportDto>> entry:mapList.entrySet()){
                    String weekday = entry.getKey();
                    List<StatisticalStudyReportDto> weekdayList = entry.getValue();
                    StatisticalStudyReportDto weekdayDto = new StatisticalStudyReportDto();
                    weekdayDto.setWeekday(weekday);
                    //计算每天的总时长
                    BigDecimal hoursSpentOfDay = weekdayList.stream().map(StatisticalStudyReportDto::getHoursSpent).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
                    weekdayDto.setHoursSpent(hoursSpentOfDay);
                    //计算每天的完成题目数
                    Integer completedQuestionsOfDay = weekdayList.stream().map(StatisticalStudyReportDto::getQuestionsCompleted).reduce(0, Integer::sum);
                    weekdayDto.setQuestionsCompleted(completedQuestionsOfDay);
                    //科目名称，逗号分隔
                    String subjectsStudied = weekdayList.stream().map(StatisticalStudyReportDto::getSubjectsStudied).distinct().collect(Collectors.joining(","));
                    weekdayDto.setSubjectsStudied(subjectsStudied);
                    List<String> list = Lists.newArrayList();
                    String[] subjectIds = subjectsStudied.split(",");
                    for(String subjectId:subjectIds){
                        DataDictionary dataDictionary = dictionaryService.selectDataDictionaryById(Integer.parseInt(subjectId));
                        list.add(dataDictionary.getCategoryName());
                    }
                    weekdayDto.setSubjectsStudieList(list);
                    weekdayDto.setDateStr(weekdayList.get(0).getDateStr());
                    resultChildList.add(weekdayDto);
                }
            }
        }
        result.setChildList(resultChildList);
        return result;
    }

    public static void main(String[] args) {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();

        // 使用默认的ISO周定义获取当前是一年中的第几周
        int weekNumber = currentDate.get(WeekFields.ISO.weekOfYear());
        System.out.println("当前是一年中的第 " + weekNumber + " 周（ISO周定义）");

    }
}
